package com.zenithmind.common.security;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * 提供简化的JWT解析功能，用于网关和各个微服务
 */
@Slf4j
public class JwtUtils {

    /**
     * 解析JWT token获取用户信息
     * @param token JWT token
     * @return 用户信息Map
     */
    public static Map<String, Object> parseToken(String token) {
        if (StringUtils.isBlank(token)) {
            throw new IllegalArgumentException("Token不能为空");
        }

        try {
            // 移除可能的前缀
            token = cleanToken(token);
            
            // 解析JWT负载
            return parseJwtPayload(token);
        } catch (Exception e) {
            log.error("Token解析失败: {}", e.getMessage());
            throw new RuntimeException("Token解析失败", e);
        }
    }

    /**
     * 从token中提取用户ID
     * @param token JWT token
     * @return 用户ID
     */
    public static String extractUserId(String token) {
        Map<String, Object> claims = parseToken(token);
        return extractUserIdFromClaims(claims);
    }

    /**
     * 从token中提取用户角色
     * @param token JWT token
     * @return 用户角色
     */
    public static String extractUserRoles(String token) {
        Map<String, Object> claims = parseToken(token);
        return extractUserRolesFromClaims(claims);
    }

    /**
     * 从claims中提取用户ID
     * @param claims JWT claims
     * @return 用户ID
     */
    public static String extractUserIdFromClaims(Map<String, Object> claims) {
        Object userId = claims.get("user_id");
        if (userId == null) {
            userId = claims.get("id");
        }
        if (userId == null) {
            userId = claims.get("userId");
        }
        return userId != null ? userId.toString() : null;
    }

    /**
     * 从claims中提取用户角色
     * @param claims JWT claims
     * @return 用户角色
     */
    public static String extractUserRolesFromClaims(Map<String, Object> claims) {
        Object roles = claims.get("roles");
        if (roles == null) {
            roles = claims.get("authorities");
        }
        return roles != null ? roles.toString() : null;
    }

    /**
     * 从claims中提取用户名
     * @param claims JWT claims
     * @return 用户名
     */
    public static String extractUsernameFromClaims(Map<String, Object> claims) {
        Object username = claims.get("username");
        if (username == null) {
            username = claims.get("sub");
        }
        return username != null ? username.toString() : null;
    }

    /**
     * 验证token是否有效（简化版本，仅检查格式）
     * @param token JWT token
     * @return 是否有效
     */
    public static boolean isValidToken(String token) {
        try {
            if (StringUtils.isBlank(token)) {
                return false;
            }
            
            token = cleanToken(token);
            String[] parts = token.split("\\.");
            
            // JWT应该有3部分：header.payload.signature
            if (parts.length != 3) {
                return false;
            }
            
            // 尝试解析payload
            parseJwtPayload(token);
            return true;
        } catch (Exception e) {
            log.debug("Token验证失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 清理token，移除可能的前缀
     */
    private static String cleanToken(String token) {
        if (token.startsWith("Bearer ")) {
            return token.substring(7);
        }
        if (token.startsWith("ZenithMind ")) {
            return token.substring(11);
        }
        return token;
    }

    /**
     * 解析JWT负载部分
     */
    private static Map<String, Object> parseJwtPayload(String token) {
        try {
            String[] parts = token.split("\\.");
            if (parts.length != 3) {
                throw new IllegalArgumentException("无效的JWT格式");
            }
            
            // 解码payload部分
            String payload = new String(Base64.getUrlDecoder().decode(parts[1]));
            return parseSimpleJson(payload);
        } catch (Exception e) {
            throw new RuntimeException("JWT解析失败: " + e.getMessage(), e);
        }
    }

    /**
     * 简化的JSON解析器
     * 注意：这是一个简化版本，仅用于解析基本的JWT payload
     */
    private static Map<String, Object> parseSimpleJson(String json) {
        Map<String, Object> result = new HashMap<>();
        
        json = json.trim();
        if (json.startsWith("{") && json.endsWith("}")) {
            json = json.substring(1, json.length() - 1);
        } else {
            return result;
        }
        
        // 简单的键值对解析
        boolean inString = false;
        int start = 0;
        
        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);
            
            if (c == '"' && (i == 0 || json.charAt(i - 1) != '\\')) {
                inString = !inString;
            } else if (!inString && c == ',') {
                String pair = json.substring(start, i).trim();
                parsePair(pair, result);
                start = i + 1;
            }
        }
        
        // 处理最后一个键值对
        if (start < json.length()) {
            String pair = json.substring(start).trim();
            parsePair(pair, result);
        }
        
        return result;
    }

    /**
     * 解析单个键值对
     */
    private static void parsePair(String pair, Map<String, Object> result) {
        int colonIndex = findColonIndex(pair);
        if (colonIndex > 0) {
            String key = pair.substring(0, colonIndex).trim();
            String value = pair.substring(colonIndex + 1).trim();
            
            // 移除键的引号
            if (key.startsWith("\"") && key.endsWith("\"")) {
                key = key.substring(1, key.length() - 1);
            }
            
            // 解析值
            Object parsedValue = parseValue(value);
            result.put(key, parsedValue);
        }
    }

    /**
     * 找到键值对中冒号的位置
     */
    private static int findColonIndex(String pair) {
        boolean inString = false;
        for (int i = 0; i < pair.length(); i++) {
            char c = pair.charAt(i);
            if (c == '"' && (i == 0 || pair.charAt(i - 1) != '\\')) {
                inString = !inString;
            } else if (!inString && c == ':') {
                return i;
            }
        }
        return -1;
    }

    /**
     * 解析JSON值
     */
    private static Object parseValue(String value) {
        value = value.trim();
        
        // 字符串值
        if (value.startsWith("\"") && value.endsWith("\"")) {
            return value.substring(1, value.length() - 1);
        }
        
        // 数字值
        if (value.matches("-?\\d+(\\.\\d+)?")) {
            try {
                if (value.contains(".")) {
                    return Double.parseDouble(value);
                } else {
                    return Long.parseLong(value);
                }
            } catch (NumberFormatException e) {
                return value;
            }
        }
        
        // 布尔值
        if ("true".equals(value) || "false".equals(value)) {
            return Boolean.parseBoolean(value);
        }
        
        // null值
        if ("null".equals(value)) {
            return null;
        }
        
        // 其他情况返回原始字符串
        return value;
    }
}
